
#include "DftShow.h"

#include "data.h"

#include <malloc.h>
#include <iostream>
#include <stdio.h>
#include <math.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>

using namespace std;

static Display *d;
static int s;
static Window w;
static GC gc;
static Colormap cmap;
static XColor bufXCol[255];

static int wWidth;
static int wHeight;
static int wCurY;

static void openWindow()
{
    d = XOpenDisplay(NULL);
    s = DefaultScreen(d);

    int blackColor = BlackPixel(d, DefaultScreen(d));
    wWidth = 600;
    wHeight = 400;
    wCurY = 0;

    w = XCreateSimpleWindow(d, DefaultRootWindow(d), 0, 0, wWidth, wHeight, 0, blackColor, blackColor);
    XSetStandardProperties(d, w,"PulseAudio DFT","PaDft", None, NULL, 0, NULL);
    XSelectInput(d, w, ExposureMask | KeyPressMask);

    XClearWindow(d, w);
    XMapRaised(d, w);
    XFlush(d);

    gc = XCreateGC(d, w, 0, NULL);
    cmap = DefaultColormap(d, s);
    for(int i=0;i<255;i++)
    {
		bufXCol[i].pixel=i;
		bufXCol[i].flags=DoRed|DoGreen|DoBlue;
		bufXCol[i].red=i*256;
		bufXCol[i].blue=i*256;
		bufXCol[i].green=i*256;
		XAllocColor(d, cmap, bufXCol+i);
	}
    //XQueryColors(d, cmap, bufXCol, 255);
    XFlush(d);
}


static void drawLine(double *DftModData, int DftModDataLen)
{
    const int NumsamplesPerPixel = DftModDataLen / wWidth;
    int iData = 0;

    for (int i=0; i<wWidth && iData<DftModDataLen; i++)
    {
        double val = 0;
        double count = 0;
        for (int is=0;is<NumsamplesPerPixel && iData<DftModDataLen; is++, iData ++)
        {
            val += DftModData[iData];
            count ++;
        }
        val = val / count * 1.5;

        int iCol = max(0, (int)min(254, (int)(val*256)));
        XSetForeground(d, gc, bufXCol[iCol].pixel);
        XDrawPoint(d, w, gc, i, wCurY);
    }
    XSetForeground(d, gc, bufXCol[0].pixel);
    for (int i=1; wCurY+i < wHeight && i<5; i++)
    {
        XDrawLine(d, w, gc, 0, wCurY+i, wWidth, wCurY+i);
    }

    XFlush(d);

    wCurY++;
    if (wCurY >= wHeight)
        wCurY = 0;
}

void *thr_show_dft_results(void *UserData)
{
    my_pa_data *paData = (my_pa_data *) UserData;
    SynchroQueue *queDftData = paData->queDftMod;
    openWindow();

    while (!queDftData->getSourceIsFinished() || queDftData->getSize() > 0)
    {
        void *pRawData = queDftData->get();
        if (pRawData == NULL)
        {
            usleep(100);
            continue;
        }

        drawLine((double *) pRawData, paData->dft->getDftWindow_NumFreqSamples());

        free(pRawData);
    }

    XFreeGC(d, gc);
	XDestroyWindow(d, w);
	XCloseDisplay(d);

    return NULL;
}

